/**
 * @fileoverview Set up simple event handler to begin example.
 *
 * This file provides the core functionality for the example application
 * included with the closure-modules build.py script.  It contains a simple
 * bootstrapping mechanism for loading another, dependent module.
 */

goog.provide('ex');
goog.provide('ex.core');
goog.provide('ex.core.App');
goog.provide('ex.core.ModuleCallback');

goog.require('goog.events');
goog.require('goog.dom');

/**
 * An instance of ex.core
 * @type {ex.core}
 * @private
 */
ex.app_ = null;

/**
 * Get the application instance.
 * @return {ex.core}
 */
ex.getApp = function() {
  return ex.app_;
};


/**
 * Application instance for our small example.
 * @constructor
 */
ex.core.App = function() {
  document.title = "Multi-Module Load Example";
  
  var depsButton = goog.dom.$('loadDeps');
  var trialButton = goog.dom.$('loadTrial');
  
  var depsHandler = goog.bind(this.loadModule, this, 'deps');
  goog.events.listen(depsButton, goog.events.EventType.CLICK, depsHandler);
  
  var trialHandler = goog.bind(this.loadModule, this, 'trial');
  goog.events.listen(trialButton, goog.events.EventType.CLICK, trialHandler);
  
/**
 * Map of module names to their load status
 * @private
 */
  this.loadedModules_ = {};
};

/**
 * Load a module.
 * @param {string} moduleName The name of the module to load.
 */
ex.core.App.prototype.loadModule = function(moduleName) {
  if(! goog.isDef(this.loadedModules_[moduleName])) {
    var script = document.createElement('script');
    script.src = 'compiled/' + moduleName + '.js';
    document.body.appendChild(script);
    
    this.loadedModules_[moduleName] = "loading";
  }
};

/**
 * Post a message in the 'status' div.
 * @param {string} message The message to post.
 */
ex.core.App.prototype.postStatusMessage = function(message) {
  goog.dom.appendChild(goog.dom.$('status'),
    goog.dom.createDom('div').appendChild(goog.dom.createTextNode(messasge))
  );
};

/**
 * @param {ex.core.ModuleCallback} callback The callback object
 */
ex.core.App.prototype.moduleLoaded = function(callback) {
  callback.callback();
  this.loadedModules_[callback.getName()] = "loaded";
};

/**
 * Superclass for a module to subclass when it loads.
 * @param {string} moduleName The name of the module that was just loaded.
 * @param {function()} callback The callbck method to be called
 *                          once the app recognizes that the module is loaded.
 * @constructor
 */
ex.core.ModuleCallback = function(moduleName, callback) {
  /**
   * @type {string}
   * @private
   */
  this.name_ = moduleName;
  
  /**
   * @type {function()}
   * @private
   */
  this.callback_ = callback;
};

/**
 * Returns the loaded module's name
 * @return {string}
 */
ex.core.ModuleCallback.prototype.getName = function() {
  return this.name_;
};

/**
 * Method called when the app recognizes that the module has loaded.
 * @return {function()}
 */
ex.core.ModuleCallback.prototype.callback = function() {
  this.callback_();
};

window.onload = function() { ex.app_ = new ex.core.App() };